package com.imdada.open.platform.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.imdada.open.platform.client.internal.req.common.ApiResponse;
import com.imdada.open.platform.config.Configuration;
import com.imdada.open.platform.exception.RpcException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
public final class ApiUtils {

    /**
     * 根据业务参数，调用达达api接口，并记录response
     *
     * @param url  api接口url
     * @param body 业务参数对象
     */
    public static void callApiWithBizParamAndLogResponse(String url, Object body) throws RpcException {
        // 构建真正的api接口参数
        Map<String, Object> params = wrapApiRequestParam(body);

        // 执行请求
        String rpcResult = HttpUtils.doPostJson(url, params);

        // 处理结果
        processResponse(rpcResult);
    }

    /**
     * 根据业务参数，调用达达api接口，并返回response
     *
     * @param url  api接口url
     * @param body 业务参数对象
     */
    public static String callApiWithBizParam(String url, Object body) {
        // 构建真正的api接口参数
        Map<String, Object> params = wrapApiRequestParam(body);

        // 执行请求
        return HttpUtils.doPostJson(url, params);
    }

    /**
     * 构建真正的api接口参数(参考文档：http://newopen.imdada.cn/#/quickStart/develop/mustRead)
     *
     * @param body 接口的body参数内容
     * @return 构建真正的api接口参数
     */
    private static Map<String, Object> wrapApiRequestParam(Object body) {
        String appSecret = Configuration.getInstance().getAppSecret();
        Map<String, Object> data = new HashMap<>();
        data.put("source_id", Configuration.getInstance().getSourceId());
        data.put("app_key", Configuration.getInstance().getAppKey());
        data.put("timestamp", LocalDateTime.now().atZone(ZoneId.systemDefault()).toEpochSecond());
        data.put("format", "json");
        data.put("v", "1.0");
        data.put("body", JSON.toJSONString(body));
        data.put("signature", signature(data, appSecret));
        return data;
    }

    /**
     * 生成签名(具体参考文档: http://newopen.imdada.cn/#/quickStart/develop/safety?_k=kklqac)
     */
    private static String signature(Map<String, Object> data, String appSecret) {
        // 请求参数按照【属性名】字典升序排序后，按照属性名+属性值拼接
        String signStr = data.keySet().stream()
                .sorted()
                .map(it -> String.format("%s%s", it, data.get(it)))
                .collect(Collectors.joining(""));

        // 拼接后的结果首尾加上appSecret
        String finalSignStr = appSecret + signStr + appSecret;

        // MD5加密并转为大写
        return DigestUtils.md5Hex(finalSignStr).toUpperCase();
    }

    /**
     * 处理结果
     */
    private static void processResponse(String rpcResult) throws RpcException {
        // 根据status判断是否执行成功
        ApiResponse<?> response = JSON.parseObject(rpcResult, new TypeReference<ApiResponse<?>>() {
        });
        if (Objects.nonNull(response) && response.success()) {
            log.info("执行成功，响应结果：{}", JSON.toJSONString(response.getResult()));
        } else {
            throw new RpcException(response.getMsg());
        }
    }

}
